<?php
/**
 * oauth client for yii
 * 
 * @author Jack Hunx (jack.hunx@gmail.com)
 */
require_once (Yii::getPathOfAlias('application.vendor') . DIRECTORY_SEPARATOR .
    'autoload.php');
class Client
{
    //array config
    private $config;
    //object client config
    private $clientConfig;
    //object token config
    private $tokenStorage;
    //object http client
    private $httpClient;
    //objec api
    private $api;
    //
    private $scope;
    private $app;
    public function __construct()
    {
        //$config = Yii::import() ;
        //if ($this->config = require_once(Yii::getPathOfAlias('application.config.client'.DIRECTORY_SEPARATOR.$this->app.'config.php'))) {
        //            throw new CException("No config file under the config directory");
        //        }
        $this->setTokenStorage();
        $this->setHttpClient();
    }
    public function init()
    {
        //must needed
    }
    private function setTokenStorage()
    {
        $this->tokenStorage = new OAuth\Client\SessionStorage();
    }
    private function setHttpClient()
    {
        $this->httpClient = new \Guzzle\Http\Client();
    }
    private function setScope()
    {
        $this->scope = new OAuth\Client\Scope($this->config['scope']);
    }
    //get config
    private function getConfig($app = null)
    {
        !is_file(Yii::getPathOfAlias('application.config.client') . DIRECTORY_SEPARATOR .
            $app . 'config.php') ? $app = null : $app;
        $this->config = require_once (Yii::getPathOfAlias('application.config.client') .
            DIRECTORY_SEPARATOR . $app . "config.php");
        $this->clientConfig = new OAuth\Client\ClientConfig($this->config['client'], $this->
            config['other']);
    }
    private function setContext()
    {
        $this->context = new OAuth\Client\Context("jack.ie@example.org", $this->scope);
    }
    private function setApi()
    {
        $this->api = new OAuth\Client\Api("foo", $this->clientConfig, $this->
            tokenStorage, $this->httpClient);
    }
    //connect to app
    public function connect($app = null)
    {
        $this->getConfig($app);
        $this->setScope();
        $this->setContext();
        $this->setApi();
        header("HTTP/1.1 302 Found");
        header("Location: " . $this->api->getAuthorizeUri($this->context));
        exit(); //$this->getConfig($app);
    }
    //call back
    public function callback($app = null, $callbackUrl)
    {
        $this->getConfig($app);
        $cb = new OAuth\Client\Callback("foo", $this->clientConfig, $this->tokenStorage,
            $this->httpClient);
        $cb->handleCallback($_GET);

        header("HTTP/1.1 302 Found");
        header("Location: {$callbackUrl}");
        exit;
    }
    /**
     * @param $app 
     * @param boolen $assoc default false
     * @return Returns an object or if the optional assoc parameter is TRUE, an associative array is instead returned. 
     */
    public function getBody($app = null, $assoc = false)
    {
        try {
            $this->getConfig($app);
            $this->setScope();
            $this->setContext();
            $this->setApi();

            $accessToken = $this->api->getAccessToken($this->context);
            if (false === $accessToken) {
                /* no valid access token available, go to authorization server */
                header("HTTP/1.1 302 Found");
                header("Location: " . $this->api->getAuthorizeUri($this->context));
                exit;
            }

            $bearerAuth = new \fkooman\Guzzle\Plugin\BearerAuth\BearerAuth($accessToken->
                getAccessToken());
            $this->httpClient->addSubscriber($bearerAuth);
            $response = $this->httpClient->get($this->config['apiUri'])->send();
            $value = html_entity_decode($response->getBody());
            return json_decode($value, $assoc);
        }
        catch (\fkooman\Guzzle\Plugin\BearerAuth\Exception\BearerErrorResponseException
            $e) {
            if ("invalid_token" === $e->getBearerReason()) {
                // the token we used was invalid, possibly revoked, we throw it away
                $api->deleteAccessToken($context);
                $api->deleteRefreshToken($context);
                /* no valid access token available, go to authorization server */
                header("HTTP/1.1 302 Found");
                header("Location: " . $api->getAuthorizeUri($context));
                exit;
            }
            throw $e;
        }
        catch (\Exception $e) {
            die(sprintf('ERROR: %s', $e->getMessage()));
        }
    }
}
